package org.fast.project.service;

import com.querydsl.core.BooleanBuilder;

import cn.hutool.core.util.StrUtil;

import org.fast.project.common.exception.UserNotFoundException;
import org.fast.project.common.utils.QueryHelpUtil;
import org.fast.project.dao.po.QUserPO;
import org.fast.project.dao.po.UserPO;
import org.fast.project.dao.repository.UserInfoDao;
import org.fast.project.service.bo.AddUserDO;
import org.fast.project.service.bo.FindUserDO;
import org.fast.project.service.bo.PageDO;
import org.fast.project.service.bo.UpdateUserDO;
import org.fast.project.service.bo.UserDO;
import org.fast.project.service.transfer.UserDo2PoTransfer;
import org.fast.project.service.transfer.UserPo2DoTransfer;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : lilith·bristol
 * @program : spring-web-archetype-service
 * @description : 用户信息服务类
 * 因为已经开启了全局cglib代理 这里可以直接使用类 无需使用接口
 * @date : 2020-04-20 01:07
 **/

@Service
public class UserInfoService {

    private final UserInfoDao userInfoDao;

    private final UserPo2DoTransfer userPo2DoTransfer;

    private final UserDo2PoTransfer userDo2PoTransfer;

    public UserInfoService(UserInfoDao userInfoDao, UserPo2DoTransfer userPo2DoTransfer,
        UserDo2PoTransfer userDo2PoTransfer) {
        this.userInfoDao = userInfoDao;
        this.userPo2DoTransfer = userPo2DoTransfer;
        this.userDo2PoTransfer = userDo2PoTransfer;
    }

    /**
     * 根据用户主键识别码获取用户数据
     *
     * @param userId 用户数据主键
     * @return {@link UserDO}
     */
    public UserDO getUser(Integer userId) {
        UserPO userPO = userInfoDao.findById(userId)
                .orElseThrow(UserNotFoundException::new);
        return userPo2DoTransfer.poToDo(userPO);
    }

    /**
     * 添加用户
     *
     * @param addUserDO 添加用户做
     * @return {@link UserDO}
     */
    public UserDO addUser(AddUserDO addUserDO) {
        UserPO userPO = userDo2PoTransfer.addDo2Po(addUserDO);
        /*
        正常情况下 这里应该加密密码再上传到数据库
        不过这只是个脚手架 所以就不写了
         */
        UserPO savedUserPo = userInfoDao.save(userPO);
        return userPo2DoTransfer.poToDo(savedUserPo);
    }

    /**
     * 更新用户
     *
     * @param updateUserDO 更新用户做
     * @return {@link UserDO}
     */
    public UserDO updateUser(UpdateUserDO updateUserDO) {
        UserPO userPO = userInfoDao.findById(updateUserDO.getUserId())
                .orElseThrow(UserNotFoundException::new);

        userDo2PoTransfer.updateUserPo(updateUserDO, userPO);
        UserPO savedUserPo = userInfoDao.save(userPO);
        return userPo2DoTransfer.poToDo(savedUserPo);
    }

    /**
     * 删除用户
     *
     * @param userId 用户id
     */
    public void deleteUser(Integer userId) {
        UserPO userPO = userInfoDao.findById(userId)
                .orElseThrow(UserNotFoundException::new);
        userInfoDao.delete(userPO);
    }

    /**
     * 查找用户
     *
     * @param findUserDO 查找用户模型对象
     * @return {@link PageDO}<{@link List}<{@link UserDO}>>
     */
    public PageDO<List<UserDO>> findUser(FindUserDO findUserDO) {
        BooleanBuilder builder = new BooleanBuilder();
        QUserPO qUserPO = QUserPO.userPO;
        if (StrUtil.isNotBlank(findUserDO.getUserName())) {
            builder.and(qUserPO.userName.like(QueryHelpUtil.allLikeQuery(findUserDO.getUserName())));
        }
        if (StrUtil.isNotBlank(findUserDO.getNickName())) {
            builder.and(qUserPO.nickName.like(QueryHelpUtil.allLikeQuery(findUserDO.getNickName())));
        }
        Page<UserPO> userPoPage = userInfoDao
                .findAll(builder, PageRequest.of(findUserDO.getPageNumber(), findUserDO.getPageSize()));

        List<UserDO> userDoList = userPoPage.get().map(userPo2DoTransfer::poToDo).collect(Collectors.toList());

        return PageDO.init(userPoPage, userDoList);
    }
}
